home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / p1123mz4.zip / HEXMAZE.CPP < prev    next >
C/C++ Source or Header  |  1994-02-14  |  49KB  |  1,236 lines

  1. #include <stdlib.h>
  2. #include <iostream.h>
  3. #include "oracle.h"
  4. #include "cell.h"
  5. #include "titillat.h"
  6. #include "hexmaze.h"
  7.  
  8. #define TRUE -1
  9. #define FALSE 0
  10.  
  11. typedef cell *cell_ptr;
  12. typedef char *char_ptr;
  13.  
  14. maze::maze(int row_count,int column_count,int thickness_of_wall,char *seed)
  15. //      Contruct a maze having "row_count" rows and "column_count" columns of
  16. // rooms.  The walls should be "thickness_of_wall" (bricks) thick.  A different
  17. // (8 character of less) "seed" generally yields a different maze.
  18.   {
  19.     struct
  20.       {
  21.          int row_num;
  22.          int column_num;
  23.       }  delta [2] [6];
  24.     int  mud_filled_room_found;
  25.     struct
  26.       {
  27.          int row_num;
  28.          int column_num;
  29.       }  next;
  30.     char wall [720] [6];
  31.     char wall_to_check;
  32.     char wall_num;
  33.     char way_out;
  34.     int  x1;
  35.     int  x2;
  36.     int  y1;
  37.     int  y2;
  38.  
  39.     wall_thickness=thickness_of_wall;
  40.     num_rows=row_count;
  41.     num_y_dots=wall_thickness*(4*num_rows+1);
  42.     y_dot_max=num_y_dots-1;
  43.     num_columns=column_count;
  44.     max_x=8*(num_columns/2)+6;
  45.     num_x_dots=wall_thickness*(max_x+1);
  46.     x_dot_max=num_x_dots-1;
  47.     // Allocate a two dimensional array of rooms.
  48.     if (memory_allocated=((room=new cell_ptr[num_rows]) != NULL))
  49.       {
  50.               int row_num=0;
  51.         while (memory_allocated && (row_num < num_rows))
  52.           if (memory_allocated=((room[row_num]=new cell [num_columns]) != NULL))
  53.             row_num++;
  54.         if (! memory_allocated)
  55.           {
  56.             while (row_num)
  57.               delete [] room[--row_num];
  58.             delete [] room;
  59.             cerr << "Fatal error:  cannot allocate maze.\n";
  60.           }
  61.       }
  62.     if (memory_allocated)
  63.       {
  64.          // Allocate a two dimensional array for plotting the maze in
  65.          // terms of "bricks" where a wall is "wall_thickness" bricks
  66.          // thick.
  67.          if (memory_allocated=((page=new char_ptr [num_y_dots]) != NULL))
  68.            {
  69.              int y_dot_num=0;
  70.              while (memory_allocated && (y_dot_num < num_y_dots))
  71.                if (memory_allocated=((page[y_dot_num]=new char [num_x_dots])
  72.                 != NULL))
  73.                  y_dot_num++;
  74.              if (! memory_allocated)
  75.                {
  76.                   while (y_dot_num)
  77.                     delete [] page[--y_dot_num];
  78.                   delete [] page;
  79.                   for (int row_num=num_rows-1; row_num >= 0; row_num--)
  80.                     delete [] room[row_num];
  81.                   delete [] room;
  82.                   cerr << "Fatal error:  cannot allocate maze.\n";
  83.                }
  84.            }
  85.          else
  86.            {
  87.               for (int row_num=num_rows-1; row_num >= 0; row_num--)
  88.                 delete [] room[row_num];
  89.               delete [] room;
  90.               cerr << "Fatal error:  cannot allocate maze.\n";
  91.            }
  92.       }
  93.     if (memory_allocated)
  94.       {
  95.          // Set up the directions by which a room can be exited.
  96.          // Directions for even columns.
  97.          delta[0][0].row_num=-1;    // north
  98.          delta[0][0].column_num=0;
  99.          delta[0][1].row_num=-1;    // northwest
  100.          delta[0][1].column_num=-1;
  101.          delta[0][2].row_num=0;     // southwest
  102.          delta[0][2].column_num=-1;
  103.          delta[0][3].row_num=1;     // south
  104.          delta[0][3].column_num=0;
  105.          delta[0][4].row_num=0;     // southeast
  106.          delta[0][4].column_num=1;
  107.          delta[0][5].row_num=-1;    // northeast
  108.          delta[0][5].column_num=1;
  109.          // Directions for odd columns.
  110.          delta[1][0].row_num=-1;    // north
  111.          delta[1][0].column_num=0;
  112.          delta[1][1].row_num=0;     // northwest
  113.          delta[1][1].column_num=-1;
  114.          delta[1][2].row_num=1;     // southwest
  115.          delta[1][2].column_num=-1;
  116.          delta[1][3].row_num=1;     // south
  117.          delta[1][3].column_num=0;
  118.          delta[1][4].row_num=1;     // southeast
  119.          delta[1][4].column_num=1;
  120.          delta[1][5].row_num=0;     // northeast
  121.          delta[1][5].column_num=1;
  122.          // Set up the 6! orders in which the wall of a room can be accessed.
  123.          int order_num=0;
  124.          for (int wall_num_1=0; wall_num_1 < 6; wall_num_1++)
  125.            for (int wall_num_2=0; wall_num_2 < 6; wall_num_2++)
  126.              if (wall_num_2 != wall_num_1)
  127.                for (int wall_num_3=0; wall_num_3 < 6; wall_num_3++)
  128.                  if ((wall_num_3 != wall_num_2)
  129.                  &&  (wall_num_3 != wall_num_1))
  130.                    for (int wall_num_4=0; wall_num_4 < 6; wall_num_4++)
  131.                      if ((wall_num_4 != wall_num_3)
  132.                      &&  (wall_num_4 != wall_num_2)
  133.                      &&  (wall_num_4 != wall_num_1))
  134.                        for (int wall_num_5=0; wall_num_5 < 6; wall_num_5++)
  135.                          if ((wall_num_5 != wall_num_4)
  136.                          &&  (wall_num_5 != wall_num_3)
  137.                          &&  (wall_num_5 != wall_num_2)
  138.                          &&  (wall_num_5 != wall_num_1))
  139.                            for (int wall_num_6=0; wall_num_6 < 6; wall_num_6++)
  140.                              if ((wall_num_6 != wall_num_5)
  141.                              &&  (wall_num_6 != wall_num_4)
  142.                              &&  (wall_num_6 != wall_num_3)
  143.                              &&  (wall_num_6 != wall_num_2)
  144.                              &&  (wall_num_6 != wall_num_1))
  145.                                {
  146.                                  wall[order_num][wall_num_6]='\0';
  147.                                  wall[order_num][wall_num_5]='\1';
  148.                                  wall[order_num][wall_num_4]='\2';
  149.                                  wall[order_num][wall_num_3]='\3';
  150.                                  wall[order_num][wall_num_2]='\4';
  151.                                  wall[order_num][wall_num_1]='\5';
  152.                                  order_num++;
  153.                                }
  154.          titillator_ptr=new titillator;
  155.          order_selector=new oracle(&seed[0],order_num);
  156.          row_selector=new oracle(&seed[0],num_rows);
  157.          column_selector=new oracle(&seed[0],num_columns);
  158.          int finished=FALSE;
  159.          // Generate mazes until you have one that is hard to solve.
  160.          do
  161.            {
  162.               // Pick a starting room.
  163.               first.column_num=column_selector->random_number();
  164.               if ((first.column_num)%2)
  165.                 do
  166.                   {
  167.                     first.row_num=row_selector->random_number();
  168.                   }
  169.                 while (first.row_num == (num_rows-1));
  170.               else
  171.                 first.row_num=row_selector->random_number();
  172.               current.row_num=first.row_num;
  173.               current.column_num=first.column_num;
  174.               // Excavate the starting room.
  175.               room[current.row_num][current.column_num].mark_floor(' ');
  176.               // Pick the order in which the walls of the starting room will be
  177.               // considered.
  178.               room[current.row_num][current.column_num].set_order(
  179.                order_selector->random_number());
  180.               titillator_ptr->titillate();
  181.               // Excavate rooms until there are no more to excavate.
  182.               do
  183.                 {
  184.                    mud_filled_room_found=FALSE;
  185.                    // Find an adjacent room (not yet considered) that needs
  186.                    // excavating.
  187.                    do
  188.                      {
  189.                         wall_num=room[current.row_num][
  190.                          current.column_num].next_wall_num();
  191.                         if (wall_num < '\6')
  192.                           {
  193.                              wall_to_check=wall[room[current.row_num][
  194.                               current.column_num].order_to_check()][wall_num];
  195.                              if (room[current.row_num][
  196.                               current.column_num].wall_up(wall_to_check))
  197.                                {
  198.                                   next.column_num=current.column_num
  199.